#!/usr/bin/env python
# coding: utf-8
#
# Copyright 2010 Alexandre Fiori
# based on the original Tornado by Facebook
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

import sys
import cyclone.web
import cyclone.auth
import cyclone.escape
from twisted.python import log
from twisted.internet import defer, reactor
import models
import agent
import json


class Application(cyclone.web.Application):
    def __init__(self):
        handlers = [
            (r"/", MainHandler),
            (r"/jsonrpc", JsonrpcHandler),
        ]
        settings = dict(
            cookie_secret="32oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o/Vo=",
        )
        cyclone.web.Application.__init__(self, handlers, **settings)


class BaseHandler(cyclone.web.RequestHandler):
    def get_current_user(self):
        user_json = self.get_secure_cookie("user")
        if not user_json:
            return None
        return cyclone.escape.json_decode(user_json)


class MainHandler(BaseHandler):
    @cyclone.web.authenticated
    def get(self):
        name = cyclone.escape.xhtml_escape(self.current_user["name"])
        self.write("Hello, " + name)


class JsonrpcHandler(cyclone.web.JsonrpcRequestHandler):

    """Initializes a service for a website, creating a database"""
    def jsonrpc_initialize_service(self, website, key, get_user,
                                    get_content, get_vote, user_pk,
                                    content_pk, vote_pk):
        hooks = {'get_user': get_user, 'get_content': get_content,
                'get_vote': get_vote, 'user_pk': user_pk,
                'content_pk': content_pk, 'vote_pk': vote_pk}

        models.create_service(website, hooks, key)
        #agent.test_service(website)
        agent.initialize_website(website)
        #agent.build_probability_profile(website)
        return {'success': True}

###METHODS ASSOCIATED WITH PLATFORM CANDIDATE GENERATION

    def jsonrpc_update_votes(self, website, key):
        if models.verify_key(website, key):
            info = models.get_from_registrar(website, ['hooks'])
            agent.initialize_votes(info, website, True, update=True)

    def jsonrpc_update(self, website, key, updatetype, params):
        if models.verify_key(website, key):
            agent.update.apply_async(args=[website,
                                        key, updatetype, params], countdown=10)
            defer.returnValue({'success': True})
        else:
            defer.returnValue({'success': False, 'error': 'Invalid Key'})

    def jsonrpc_candidate_platforms(self, website, key, obj_id, k):
        if models.verify_key(website, key):
            #generates candidate platforms for Group with object_pk == obj_id from website
            results = agent.candidate_platforms(website, obj_id, k)
            return {'candidates': results}

###VOTING METHODS FROM PYVOTECORE EXPOSED ON AGENT
###PUBLIC METHODS

    def jsonrpc_schulze_method(self, ballots):
        ret_dict = agent.schulze_method(ballots)
        return {'winner': ret_dict['winner']}

###ETC

    def jsonrpc_add(self):
        return {'add': 2 + 2}

    def jsonrpc___repr__(self):
        #keeps GAE off our backs
        return {'fuckoff': True}

    @defer.inlineCallbacks
    def jsonrpc_geoip_lookup(self, address):
        result = yield cyclone.httpclient.fetch("http://freegeoip.net/json/%s"
                                                    % address.encode("utf-8"))
        defer.returnValue(result.body)


def main():
    reactor.listenTCP(8888, Application())
    reactor.run()

if __name__ == "__main__":
    log.startLogging(sys.stdout)
    main()
